package ru.ipo.dces.plugins.admin.components;

import info.clearthought.layout.TableLayout;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import static java.awt.event.KeyEvent.VK_ENTER;

public class JTableSearcher extends JPanel {
    private ContestUsersTable table;
    private JTextField searchArea = new JTextField();
    private JButton searchButton = new JButton("Поиск");
    private static int row = 0;
    private static int column = 0;
    private boolean substringFounded = false;
    private ActionListener searchActionListener = new ActionListener() {
        @Override
            public void actionPerformed(ActionEvent actionEvent) {
                int rows = table.getRowCount();
                if (rows == 0)
                    return;

                String searchingText = searchArea.getText();
                if (searchingText.equals(""))
                    return;

            int c = column;
            int r = row;
            while (true) {
                for (; r < rows; r++) {
                    for (; c < table.getColumnCount(); c++) {
                        String cellText;
                        if (table.getValueAt(r, c) == null)
                            cellText = "";
                        else
                            cellText = table.getValueAt(r, c).toString();
                        if (cellText.contains(searchingText)) {
                            substringFounded = true;
                            table.setCellSelectionEnabled(true);
                            table.changeSelection(r, c, false, false);
                            if (c == table.getColumnCount() - 1 && r < rows - 1) {
                                row = r + 1;
                                column = 0;
                                return;
                            }
                            if (c == table.getColumnCount() - 1 && r == rows - 1) {
                                row = 0;
                                column = 0;
                                return;
                            }
                            row = r;
                            column = c + 1;
                            return;
                        }
                    }
                    c = 0;
                }
                r = 0;
                c = 0;
                if (!substringFounded) {
                    searchArea.setForeground(Color.RED);
                    return;
                }
                resetState();
            }
        }
    };

    public void resetPanel() {
        resetState();
        searchArea.setText("");
    }

    private void resetState() {
        substringFounded = false;
        searchArea.setForeground(Color.BLACK);
        row = 0;
        column = 0;
    }

    public JTableSearcher(ContestUsersTable table) {
        this.table = table;
        int separatorGap = 5;
        setLayout(new TableLayout(
                new double[] {TableLayout.FILL, separatorGap, TableLayout.PREFERRED},
                new double[] {TableLayout.PREFERRED, TableLayout.PREFERRED}
        ));
        searchArea.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        add(new JLabel("Поиск в таблице"), "0, 0, 2, 0");
        add(searchArea, "0, 1");
        add(searchButton, "2, 1");
        addListeners();
    }

    private void addListeners() {
        searchButton.addActionListener(searchActionListener);
        searchArea.registerKeyboardAction(searchActionListener, KeyStroke.getKeyStroke(VK_ENTER, 0, false), WHEN_FOCUSED);

        table.addRegistrationListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                resetPanel();
            }
        });

        searchArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent documentEvent) {
                resetState();
            }

            @Override
            public void removeUpdate(DocumentEvent documentEvent) {
                resetState();
            }

            @Override
            public void changedUpdate(DocumentEvent documentEvent) {
                resetState();
            }
        });
    }
}
